package com.boho.ecp.order.service;

import java.math.BigDecimal;
import java.math.RoundingMode;
import java.sql.Connection;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.apache.commons.lang.StringUtils;

import cn.boho.framework.context.ActionContext;
import cn.boho.framework.po.ComboPager;
import cn.boho.framework.po.DynaBeanMap;
import cn.boho.framework.po.POUtils;
import cn.boho.framework.po.Pager;
import cn.boho.framework.po.SArrayList;
import cn.boho.framework.utils.DateUtils;
import cn.boho.framework.utils.HTMLFilter;

import com.boho.ecp.base.model.Product;
import com.boho.ecp.cart.dao.CartDao;
import com.boho.ecp.constant.Member;
import com.boho.ecp.constant.Order;
import com.boho.ecp.member.dao.TDeliveryAddressDao;
import com.boho.ecp.member.service.MemberService;
import com.boho.ecp.order.dao.TOrderDao;
import com.boho.ecp.po.TOrderChangeLogPO;
import com.boho.ecp.po.TOrderDetailPO;
import com.boho.ecp.po.TOrderPO;
import com.boho.ecp.product.service.ProductService;
import com.boho.ecp.util.ArrayUtils;
import com.boho.ecp.util.JsonUtils;
import com.boho.ecp.util.SeqManager;
import com.google.gson.reflect.TypeToken;


public class OrderService {
	
	/**
	 * 新增订单
	 * @param atx
	 * @return
	 * @throws Exception
	 */
	public static String newOrder(ActionContext atx, Connection con) throws Exception{
		Integer memberId = (Integer)atx.getSessionValue(Member.MEMBER_ID_SESSION);
		atx.setIntValue("MEMBER_ID", memberId);
		DynaBeanMap paymentProduct = getPaymentProduct(con, memberId);
		String amount = (String)paymentProduct.get("AMOUNT");
		List productList = (List)paymentProduct.get("PRODUCT_LIST");
		List orderProductList = (List)paymentProduct.get("ORDER_PRODUCT_LIST");
		Integer mid = atx.getIntegerValue("MID");
		if(mid == 0){
			mid = MemberService.addDeliveryAddress(atx, con, memberId);
		}
		DynaBeanMap addressDbm = TDeliveryAddressDao.getTDeliveryAddressByPk(con, mid);
		StringBuilder finalAddress = new StringBuilder();
		finalAddress.append((String)addressDbm.get("PROVINCE"))
					.append((String)addressDbm.get("CITY"))
					.append((String)addressDbm.get("COUNTY"))
					.append((String)addressDbm.get("DELIVERY_ADDRESS"));
		
		Integer points = (Integer)paymentProduct.get("POINTS");
		
		Date date = new Date();
		SeqManager sm = SeqManager.getInstance();
		String orderId = sm.getSeq("yyyyMMddhhmmss","seq_order").toString();
		TOrderPO tOrderPO = new TOrderPO();
		tOrderPO.setOrderId(orderId);
		tOrderPO.setProduct(JsonUtils.toJSON(orderProductList));
		tOrderPO.setStatus(Order.WAIT_STATUS); //目前没有付款环节，直接跳到等待处理状态
		tOrderPO.setOrderDate(date);
		tOrderPO.setMessage(HTMLFilter.filter(atx.getStringValue("MESSAGE","")));
		tOrderPO.setMid(mid);
		tOrderPO.setConsignee((String)addressDbm.get("CONSIGNEE_NAME"));
		tOrderPO.setMobile((String)addressDbm.get("MOBILE"));
		tOrderPO.setTelephone((String)addressDbm.get("TELEPHONE"));
		tOrderPO.setZipCode((String)addressDbm.get("ZIP_CODE"));
		tOrderPO.setFinalAddress(finalAddress.toString());
		tOrderPO.setDeliverTime(atx.getIntegerValue("DELIVER_TIME"));
		tOrderPO.setDeliverMethod(atx.getIntegerValue("DELIVER_METHOD"));
		tOrderPO.setPayMethod(atx.getIntegerValue("PAY_METHOD"));
		tOrderPO.setOrderPoints(points);
		tOrderPO.setPayment(new BigDecimal(amount));
		tOrderPO.setMemberId(memberId);
		tOrderPO.setCreateBy(memberId.toString());
		tOrderPO.setCreateDate(date);
		POUtils.insert(con, tOrderPO,false);
		
		SArrayList poList = new SArrayList();
		List idList = new ArrayList();
		for (Object object : productList) {
			DynaBeanMap dbm = (DynaBeanMap)object;
			TOrderDetailPO orderDetailPO = new TOrderDetailPO();
			Integer productId = (Integer)dbm.get("PRODUCT_ID");
			orderDetailPO.setOrderId(orderId);
			orderDetailPO.setProductId(productId);
			orderDetailPO.setProductNo((String)dbm.get("PRODUCT_NO"));
			orderDetailPO.setProductName((String)dbm.get("PRODUCT_NAME"));
			orderDetailPO.setMarketPrice((BigDecimal)dbm.get("MARKET_PRICE"));
			orderDetailPO.setMemberPrice((BigDecimal)dbm.get("MEMBER_PRICE"));
			orderDetailPO.setPhotoUrl((String)dbm.get("PHOTO_URL"));
			orderDetailPO.setQty((Integer)dbm.get("QTY"));
			orderDetailPO.setPoint((Integer)dbm.get("POINT"));
			orderDetailPO.setAmount((BigDecimal)dbm.get("AMOUNT"));
			orderDetailPO.setMemberId(memberId);
			orderDetailPO.setOrderDate(date);
			orderDetailPO.setCreateBy(memberId.toString());
			orderDetailPO.setCreateDate(date);
			poList.add(orderDetailPO);
			idList.add(productId);
		}
		POUtils.insertPoList(con, poList, false);
		addOrderChangeLog(con, orderId, Order.WAIT_STATUS, date, "您提交了订单，请等待系统确认", "客户", memberId.toString());
		ProductService.batchUpdateBuyByProductIds(con, idList);
		return orderId;
	}
	
	/**
	 * 根据订单编号查询订单信息
	 * @param con
	 * @param orderId
	 * @param memberId
	 * @return
	 * @throws Exception
	 */
	public static DynaBeanMap getOrderById(Connection con, String orderId, Integer memberId) throws Exception{
		DynaBeanMap dbm = TOrderDao.getTOrderByPk(con, orderId, memberId);
		List list = TOrderDao.getOrderDetailById(con, orderId);
		dbm.put("PRODUCT", JsonUtils.toJSON(list));
		return dbm;
	}
	
	/**
	 * 获取订单详细信息
	 * @param con
	 * @param orderId
	 * @param memberId
	 * @return
	 * @throws Exception
	 */
	public static DynaBeanMap getOrderDetailById(Connection con, String orderId, Integer memberId) throws Exception {
		DynaBeanMap dbm = new DynaBeanMap();
		DynaBeanMap orderDbm = getOrderById(con, orderId, memberId);
		List detailList = TOrderDao.getOrderDetailById(con, orderId);
		List logList = TOrderDao.queryOrderLogList(con, orderId);
		Integer deliverId = (Integer)orderDbm.get("MID");
		DynaBeanMap flowDbm = getOrderProccessFlow(logList);
		dbm.put("ORDER", orderDbm);
		dbm.put("DETAIL", detailList.toArray());
		dbm.put("LOG", logList.toArray());
		dbm.put("FLOW", flowDbm);
		return dbm;
	}
	
	/**
	 * 获取订单处理状态处理时间
	 * @param logList
	 * @return
	 */
	public static DynaBeanMap getOrderProccessFlow(List logList){
		DynaBeanMap m = new DynaBeanMap();
		m.put("WAIT_STATUS", 0);
		m.put("PROCESS_STATUS", 0);
		m.put("OUT_BOUND_STATUS", 0);
		m.put("DELIVER_STATUS", 0);
		m.put("FINISH_STATUS", 0);
		for (Object object : logList) {
			DynaBeanMap dbm = (DynaBeanMap)object;
			Integer status = (Integer)dbm.get("STATUS");
			Date date = DateUtils.TimestampToDate(dbm.get("CHANGE_DATE"));
			long time = date.getTime();
			if(status == Order.WAIT_STATUS){
				m.put("WAIT_STATUS", time);
			}
			else if(status == Order.PROCESS_STATUS){
				m.put("PROCESS_STATUS", time);
			}
			else if(status == Order.OUT_BOUND_STATUS){
				m.put("OUT_BOUND_STATUS", time);
			}
			else if(status == Order.DELIVER_STATUS){
				m.put("DELIVER_STATUS", time);
			}
			else if(status == Order.FINISH_STATUS){
				m.put("FINISH_STATUS", time);
			}
		}
		return m;
	}	
	/**
	 * 添加订单状态改变信息
	 * @param con
	 * @param orderId
	 * @param status
	 * @param date
	 * @param content
	 * @param operatorName
	 * @param createBy
	 * @throws Exception
	 */
	public static void addOrderChangeLog(Connection con, String orderId, int status, Date date, 
			String content, String operatorName, String createBy) throws Exception{
		TOrderChangeLogPO changeLogPO = new TOrderChangeLogPO();
		changeLogPO.setOrderId(orderId);
		changeLogPO.setStatus(status);
		changeLogPO.setChangeDate(date);
		changeLogPO.setContent(content);
		changeLogPO.setOperatorName(operatorName);
		changeLogPO.setCreateBy(createBy);
		changeLogPO.setCreateDate(date);
		POUtils.insert(con, changeLogPO, false);
	}
	
	/**
	 * 根据条件查询订单信息
	 * @param con
	 * @param pager
	 * @param memberId
	 * @param productName
	 * @param status
	 * @param date
	 * @return
	 * @throws Exception
	 */
	public static ComboPager queryTOrderPagerByMemberId(Connection con, Pager pager, Integer memberId, String productName,
			int status, Integer date) throws Exception{
		ComboPager cp = TOrderDao.queryTOrderPagerByMemberId(con, pager, memberId, productName, status, date);
		List list = cp.getRs();
		List idList = new ArrayList();
		for (Object object : list) {
			DynaBeanMap dbm = (DynaBeanMap)object;
			String orderId = (String)dbm.get("ORDER_ID");
			idList.add(orderId);
		}
		List detailList = queryOrderDetailList(con, idList);
		DynaBeanMap map = new DynaBeanMap();
		for (Object object : detailList) {
			DynaBeanMap m = (DynaBeanMap)object;
			String orderId = (String)m.get("ORDER_ID");
			List tlist = null;
			if(map.containsKey(orderId)){
				tlist = (List)map.get(orderId);
				tlist.add(m);
			}
			else{
				tlist = new ArrayList();
				tlist.add(m);
			}
			map.put(orderId, tlist);
		}
		for (Object object : list) {
			DynaBeanMap dbm = (DynaBeanMap)object;
			String orderId = (String)dbm.get("ORDER_ID");
			List pList = (List)map.get(orderId);
			dbm.put("PRODUCT", JsonUtils.toJSON(pList));
		}
		return cp;
	}
	
	/**
	 * 根据ID列表查询订单详细信息
	 * @param con
	 * @param idList
	 * @return
	 * @throws Exception
	 */
	public static List queryOrderDetailList(Connection con, List idList) throws Exception {
		String ids = ArrayUtils.toArray(idList);
		if(StringUtils.isBlank(ids)){
			ids = "'-1'";
		}
		return TOrderDao.queryOrderDetailList(con, ids);
	}
	
	/**
	 * 
	 * @param con
	 * @param orderId
	 * @param memberId
	 * @return
	 * @throws Exception
	 */
	public static TOrderPO getOrderPOById(Connection con, String orderId, Integer memberId) throws Exception {
		TOrderPO tOrderPO = new TOrderPO();
		DynaBeanMap dynaBeanMap = getOrderById(con, orderId, memberId);
		if(dynaBeanMap!=null){
			tOrderPO.setOrderId(dynaBeanMap.get("ORDER_ID")==null?null:(String)dynaBeanMap.get("ORDER_ID"));
			tOrderPO.setProduct(dynaBeanMap.get("PRODUCT")==null?null:(String)dynaBeanMap.get("PRODUCT"));
			tOrderPO.setStatus(dynaBeanMap.get("STATUS")==null?null:(Integer)dynaBeanMap.get("STATUS"));
			tOrderPO.setMid(dynaBeanMap.get("MID")==null?null:(Integer)dynaBeanMap.get("MID"));
			tOrderPO.setConsignee(dynaBeanMap.get("PRODUCT")==null?null:(String)dynaBeanMap.get("PRODUCT"));
			tOrderPO.setMobile(dynaBeanMap.get("MOBILE")==null?null:(String)dynaBeanMap.get("MOBILE"));
			tOrderPO.setTelephone(dynaBeanMap.get("TELEPHONE")==null?null:(String)dynaBeanMap.get("TELEPHONE"));
			tOrderPO.setZipCode(dynaBeanMap.get("ZIP_CODE")==null?null:(String)dynaBeanMap.get("ZIP_CODE"));
			tOrderPO.setFinalAddress(dynaBeanMap.get("FINAL_ADDRESS")==null?null:(String)dynaBeanMap.get("FINAL_ADDRESS"));
			tOrderPO.setDeliverTime(dynaBeanMap.get("DELIVER_TIME")==null?null:(Integer)dynaBeanMap.get("DELIVER_TIME"));
			tOrderPO.setPayMethod(dynaBeanMap.get("PAY_METHOD")==null?null:(Integer)dynaBeanMap.get("PAY_METHOD"));
			tOrderPO.setDeliverMethod(dynaBeanMap.get("DELIVER_METHOD")==null?null:(Integer)dynaBeanMap.get("DELIVER_METHOD"));
			tOrderPO.setOrderPoints(dynaBeanMap.get("ORDER_POINTS")==null?null:(Integer)dynaBeanMap.get("ORDER_POINTS"));
			tOrderPO.setPayment(dynaBeanMap.get("PAYMENT")==null?null:(BigDecimal)dynaBeanMap.get("PAYMENT"));
			tOrderPO.setMemberId(dynaBeanMap.get("MEMBER_ID")==null?null:(Integer)dynaBeanMap.get("MEMBER_ID"));
			tOrderPO.setProcessUserId(dynaBeanMap.get("PROCESS_USER_ID")==null?null:(Integer)dynaBeanMap.get("PROCESS_USER_ID"));
			tOrderPO.setIsValid(dynaBeanMap.get("IS_VALID")==null?null:(Integer)dynaBeanMap.get("IS_VALID"));
			tOrderPO.setCreateBy(dynaBeanMap.get("CREATE_BY")==null?null:(String)dynaBeanMap.get("CREATE_BY"));
			tOrderPO.setCreateDate(DateUtils.TimestampToDate(dynaBeanMap.get("CREATE_DATE")));
			tOrderPO.setUpdateBy(dynaBeanMap.get("UPDATE_BY")==null?null:(String)dynaBeanMap.get("UPDATE_BY"));
			tOrderPO.setUpdateDate(DateUtils.TimestampToDate(dynaBeanMap.get("UPDATE_DATE")));
		}
		return tOrderPO;
	}
	
	
	/**
	 * 取得需要付费的商品
	 * @param con
	 * @param memberId
	 * @return
	 * @throws Exception
	 */
	private static DynaBeanMap getPaymentProduct(Connection con, Integer memberId) throws Exception {
		DynaBeanMap dbm = CartDao.getCartByMemberId(con, memberId);
		List<Product> list = JsonUtils.fromJson((String)dbm.get("PRODUCT"), new TypeToken<List<Product>>(){}.getType());
		
		List<Integer> idList = new ArrayList<Integer>();
		Map<Integer, Integer> map = new HashMap<Integer, Integer>();
		for (Product product : list) {
			idList.add(product.getId());
			map.put(product.getId(), product.getQty());
		}
		List<DynaBeanMap> productList = ProductService.getProductByIds(con, idList);
		DynaBeanMap cartProduct = fillCartProduct(productList, map);
		return cartProduct;
	}
	
	/**
	 * 填充需要付费的商品信息
	 * @param list
	 * @param map
	 * @return
	 * @throws Exception
	 */
	private static DynaBeanMap fillCartProduct(List<DynaBeanMap> list, Map<Integer, Integer> map) throws Exception {
		DynaBeanMap cart = new DynaBeanMap();
		List productList = new ArrayList();
		List orderProductList = new ArrayList(); // 供搜索产品的时候使用
		BigDecimal amount = new BigDecimal(0);
		BigDecimal points = new BigDecimal(0);
		for (DynaBeanMap dbm : list) {
			DynaBeanMap m = new DynaBeanMap();
			
			Integer productId = (Integer)dbm.get("PRODUCT_ID");
			String productNo = (String)dbm.get("PRODUCT_NO");
			String productName = (String)dbm.get("PRODUCT_NAME");
			BigDecimal price = (BigDecimal)dbm.get("MEMBER_PRICE");
			String photoUrl = (String)dbm.get("PHOTO_URL");
			price = price.setScale(2, RoundingMode.HALF_UP);
			BigDecimal marketPrice = (BigDecimal)dbm.get("MARKET_PRICE");
			marketPrice = marketPrice.setScale(2, RoundingMode.HALF_UP);
			
			Integer qty = map.get(productId);
			BigDecimal singlePrice = price.multiply(new BigDecimal(qty));
			singlePrice = singlePrice.setScale(2, RoundingMode.HALF_UP);
			amount = amount.add(singlePrice);
			
			points = points.add(singlePrice);
			
			m.put("PRODUCT_ID", productId);
			m.put("PRODUCT_NO", productNo);
			m.put("PRODUCT_NAME", productName);
			m.put("QTY", qty);
			m.put("AMOUNT", singlePrice);
			m.put("POINT", singlePrice.multiply(new BigDecimal(com.boho.ecp.constant.Product.POINT_RATE)).toBigInteger().intValue()); //积分
			m.put("MEMBER_PRICE",price);
			m.put("MARKET_PRICE", marketPrice);
			m.put("PHOTO_URL", photoUrl);
			productList.add(m);
			
			DynaBeanMap pm = new DynaBeanMap();
			pm.put("PRODUCT_ID", productId);
			pm.put("PRODUCT_NAME", productName);
			orderProductList.add(pm);
		}
		amount = amount.setScale(2, RoundingMode.HALF_UP);
		cart.put("AMOUNT", amount.toString());
		cart.put("PRODUCT_LIST", productList);
		cart.put("ORDER_PRODUCT_LIST", orderProductList);
		cart.put("POINTS", points.multiply(new BigDecimal(com.boho.ecp.constant.Product.POINT_RATE)).toBigInteger().intValue()); // 积分
		return cart;
	}
	
	/**
	 * 修改订单状态
	 * @param con
	 * @param orderId
	 * @param status
	 * @param operator
	 * @throws Exception
	 */
	public static void updateOrderStatus(Connection con, String orderId, int status, String operator) throws Exception {
		TOrderPO cPO = new TOrderPO();
		TOrderPO vPO = new TOrderPO();
		cPO.setOrderId(orderId);
		vPO.setStatus(status);
		vPO.setUpdateBy(operator);
		vPO.setUpdateDate(new Date());
		POUtils.update(con, cPO, vPO, false);
	}
	
	/**
	 * 修改是否已评论状态
	 * @param con
	 * @param orderId
	 * @param status
	 * @param operator
	 * @throws Exception
	 */
	public static void updateOrderCommentStatus(Connection con, String orderId, int status, String memberId) throws Exception{
		TOrderPO cPO = new TOrderPO();
		TOrderPO vPO = new TOrderPO();
		cPO.setOrderId(orderId);
		vPO.setIsComment(status);
		vPO.setUpdateBy(memberId);
		vPO.setUpdateDate(new Date());
		POUtils.update(con, cPO, vPO, false);
	}
	
}
